
var COSTSHEET = 
{
	'_ratehrSvcOT' 		: 'custbody_tti_fieldservothrrate',
	'_ratehrSvc'   		: 'custbody_tti_fieldservhrrate',
	'_ratehrDLOT'  		: 'custbody_tti_dlothrrate',
	'_ratehrDL'	   		: 'custbody_tti_dlhrrate',
	'_totalHrsSvcOT'	: 'custbody_tti_fieldservottotalhrs',
	'_totalHrsSvc'		: 'custbody_tti_fieldservtotalhrs',
	'_totalHrsDLOT'	    : 'custbody_tti_dlovertimetotalhrs',
	'_totalHrsDL'		: 'custbody_tti_dltotalhrs',
	'_contriPercent'	: 'custbody_tti_contripercent',
	'_contribution'		: 'custbody_tti_contribution',
	'_ohHours'			: 'custbody_tti_ohhours',
	'_overheads'		: 'custbody_tti_overheadtext',
	'_grossProPercent'	: 'custbody_tti_gppercent',
	'_grossProfit'		: 'custbody_tti_grossprofit',
	'_totalDirectCost'	: 'custbody_tti_totaldirectcost',
	'_financialCost'	: 'custbody_tti_financialcost',
	'_lcCharges'		: 'custbody_tti_lccharges',
	'_commissionAgent'	: 'custbody_tti_commagent',
	'_commissionStaff'	: 'custbody_tti_commstaff',
	'_travelEntertain'	: 'custbody_tti_travelentertainment',
	'_warrantyCost'		: 'custbody_tti_warranty',
	'_localOverTranspo'	: 'custbody_tti_localoverseastranspo',
	'_insuranceMarine'	: 'custbody_tti_insurancemarinecargo',
	'_freightShipping'	: 'custbody_tti_freightshift',
	'_crafting'			: 'custbody_tti_crafting',
	'_directIndServices': 'custbody_tti_directindirectserv',
	'_materialCost'		: 'custbody_tti_matcost',
	'_overtimeFldSvc'	: 'custbody_tti_otfieldservice',
	'_fieldSvc'			: 'custbody_tti_fieldservice',
	'_overtimeDirectLab': 'custbody_tti_otdirectlabourmanu',
	'_directLabour'		: 'custbody_tti_directlabourmanufacturing',
	'_directCost'		: 'custbody_tti_directcost',
	'_sellPriceEst'		: 'custbody_tti_sellprice',
	'_creditMTH'		: 'custbody_tti_fin_cost_credit_mth',
	'_rateOH'			: 'custbody_tti_ohhrrate',
	'_totalohHours'		: 'custbody_tti_ohtotalhrs',
	'_amount'			: 'custbody_tti_fin_cost_amount',
	'_comPercent'		: 'custbody_tti_commission_percentage',
	'_comInsurance'		: 'custbody_tti_insurance_percentage',
	'_sellPriceLoc'     : 'custbody_tti_sellprice_local'
};

var MULTIPLIER = {
	'_percent'			: 100,
	'_monthsPerYear'	: 12,
	'_insMarineCargo'	: 0.005,
	'_financialCost'    : 0.08
};

var ERROR_MESSAGE = {
	'_grossMargin'   	: "ERROR: Selling Price or Gross Profit % must not be empty"
};

var ITEM_LINE = {
	'_costItemLine' : 1 
};


/**
 * Initial function to be called - Before Load
 *
 * @returns {Void} 
 */
function beforeLoad_Quotation(type, form, request)
{
    var ST_TITLE_LOG  = "beforeLoad_Quotation";
	try
	{
	    nlapiLogExecution('DEBUG', ST_TITLE_LOG, "type = "+type);
		if(type == 'edit' || type == 'create')
		{
			
			//Set script
			var stItemId = nlapiGetContext().getSetting('SCRIPT',  'custscript_item_holder');
			var stCompanyCurr = nlapiGetContext().getSetting('SCRIPT',  'custscript_company_currency');
			nlapiLogExecution('DEBUG', ST_TITLE_LOG, "stItemId = "+stItemId);
			
			form.setScript('customscript_pge_ue_cost_calculations');
			
			//Set buttons
			setButton('custpage_calculate', 'Calculate', 'custom351', "calculateCostSheet("+stCompanyCurr+")");
			setButton('custpage_clear'	  , 'Clear'    , 'custom351', "clearCostSheet()");
			setButton('custpage_submit'	  , 'Submit'   , 'custom351', "submitCostSheet("+stItemId+")");
			
		}
	}
	catch (error)
	{
		if (error.getDetails != undefined)
        {
           nlapiLogExecution('ERROR','Process Error',  error.getCode() + ': ' + error.getDetails());
           throw error;
        }
        else
        {
           nlapiLogExecution('ERROR','Unexpected Error', error.toString()); 
           throw nlapiCreateError('99999', error.toString());
        }
	}
}


/**
 * This function will do the necessary computations to get the gross Profit
 * 
 * @returns {Void} 
 */
function calculateCostSheet(stCompanyCurr)
{

	var ST_TITLE_LOG  = "calculateCostSheet";
	
	var flSellPrice = parseFloatHelper(nlapiGetFieldValue(COSTSHEET._sellPriceEst));
	var flGrossPercent = parseFloatHelper(nlapiGetFieldValue(COSTSHEET._grossProPercent));

	if(!flSellPrice && !flGrossPercent)
	{
		alert(ERROR_MESSAGE._grossMargin);
		return;
	}
	
	//Compute Overtime Direct Labour - Manufacturing
	computeTotalRateBasedonHours(COSTSHEET._totalHrsDLOT, COSTSHEET._ratehrDLOT, COSTSHEET._overtimeDirectLab);
	
	//Compute Direct Labour - Manufacturing
	computeTotalRateBasedonHours(COSTSHEET._totalHrsDL, COSTSHEET._ratehrDL, COSTSHEET._directLabour);
	
	//Compute Field Service
	computeTotalRateBasedonHours(COSTSHEET._totalHrsSvc, COSTSHEET._ratehrSvc, COSTSHEET._fieldSvc);
	
	//Compute Overtime Field Service
	computeTotalRateBasedonHours(COSTSHEET._totalHrsSvcOT, COSTSHEET._ratehrSvcOT, COSTSHEET._overtimeFldSvc);
	
	//Compute OH Hours
	computeTotalRateBasedonHours(COSTSHEET._totalohHours, COSTSHEET._rateOH, COSTSHEET._ohHours);
	
	//Compute for the Insurance Marine / Cargo
	var flMaterialCost = parseFloatHelper(nlapiGetFieldValue(COSTSHEET._materialCost));
	var flInsuranceMarineCargo = flMaterialCost * MULTIPLIER._insMarineCargo;
	nlapiSetFieldValue(COSTSHEET._insuranceMarine, flInsuranceMarineCargo);
	
	//Compute for the Financial Cost
	var flCreditMTH = parseFloatHelper(nlapiGetFieldValue(COSTSHEET._creditMTH));
	var flAmount    = parseFloatHelper(nlapiGetFieldValue(COSTSHEET._amount));
	var flFinancialCost = (flCreditMTH * flAmount ) * (MULTIPLIER._financialCost / MULTIPLIER._monthsPerYear);
	nlapiSetFieldValue(COSTSHEET._financialCost, flFinancialCost);

	//Compute GrossProfit
	var arrCostFlds = [COSTSHEET._directLabour		,  COSTSHEET._overtimeDirectLab		,	COSTSHEET._fieldSvc				,
					   COSTSHEET._overtimeFldSvc	,  COSTSHEET._materialCost			,   COSTSHEET._directIndServices	,
					   COSTSHEET._crafting			,  COSTSHEET._freightShipping		,   COSTSHEET._insuranceMarine		,
					   COSTSHEET._localOverTranspo	,  COSTSHEET._warrantyCost			,   COSTSHEET._travelEntertain		,
					   COSTSHEET._commissionStaff	,  COSTSHEET._commissionAgent		,   COSTSHEET._lcCharges			,
					   COSTSHEET._financialCost
					  ];
	
	var flTotalCost = addTotalCost(arrCostFlds);
	
	//Compute for Total Direct Cost
	nlapiSetFieldValue(COSTSHEET._totalDirectCost, flTotalCost);

	//Compute for Gross Profit
	var flGrossMargin = 0;
	var percentGrossMargin = parseFloatHelper(nlapiGetFieldValue(COSTSHEET._grossProPercent)); 
	if(flSellPrice)
	{
		flGrossMargin = flSellPrice - flTotalCost;
		nlapiSetFieldValue(COSTSHEET._grossProfit, flGrossMargin);
		
		//Compute for Gross Profit %
		percentGrossMargin = (flGrossMargin / flSellPrice)* MULTIPLIER._percent;
	} else 
	{
		//Compute for sell price
		flSellPrice = flTotalCost / (1 - (percentGrossMargin/100));
		nlapiSetFieldValue(COSTSHEET._sellPriceEst, flSellPrice);
		
		flGrossMargin = flSellPrice - flTotalCost;
		nlapiSetFieldValue(COSTSHEET._grossProfit, flGrossMargin);
	}
	
	//Compute for Contribution
	var flohHours = parseFloatHelper(nlapiGetFieldValue(COSTSHEET._ohHours));
	var flContribution = flGrossMargin - flohHours;
	nlapiSetFieldValue(COSTSHEET._contribution, flContribution);
	
	//Compute for Contribution %
	var percentContribution = (flContribution / flSellPrice)* MULTIPLIER._percent;
	
	if(flSellPrice > flTotalCost) 
	{
		nlapiSetFieldValue(COSTSHEET._grossProPercent, percentGrossMargin);
		nlapiSetFieldValue(COSTSHEET._contriPercent, percentContribution);
	} 
	else 
	{
		alert("Sell Price must be greater than the Total Cost");
	}
	
	//Compute for Local Selling price
	var stSubsidiary = nlapiGetFieldValue('subsidiary');
	if(stSubsidiary)
	{
		var stSourceCurr = nlapiLookupField('subsidiary', stSubsidiary, 'currency');
	    var stTargetCurrency = stCompanyCurr;
	    if(stSourceCurr && stTargetCurrency) 
	    {
	    	var stSellPriceLoc = nlapiExchangeRate(stSourceCurr, stTargetCurrency, nlapiDateToString(new Date()));
	    	nlapiSetFieldValue(COSTSHEET._sellPriceLoc, stSellPriceLoc);
	    }
	}
	
}

/**
 * This function sets the total cost in the total field
 * 
 * @returns {Void} 
 */
function submitCostSheet(stItemId)
{
	var ST_TITLE_LOG  = "submitCostSheet";
	
	var stItemFirstLine = nlapiGetLineItemValue('item', 'item', ITEM_LINE._costItemLine);
	var flAmount = parseFloatHelper(nlapiGetFieldValue("custbody_tti_sellprice"));
	
	if(!flAmount) {
			alert ("Sell Price is Required");
			return;
	};
	
	if(stItemFirstLine && stItemFirstLine == stItemId)
	{
		nlapiSelectLineItem('item',  ITEM_LINE._costItemLine);
	} 
	else 
	{
		nlapiInsertLineItem('item',  ITEM_LINE._costItemLine);
	}
	
	// set the item and location values on the currently selected line
	nlapiSetCurrentLineItemValue('item', 'item' , stItemId	, true	, true);
	nlapiSetCurrentLineItemValue('item', 'rate' , flAmount  , true  , true);
	
	// commit the line to the database
	nlapiCommitLineItem('item');
	
}


/**
 * This function clears all the field except the material cost field
 * 
 * @returns {Void} 
 */
function clearCostSheet()
{
    var ST_TITLE_LOG  = "clearCostSheet";
	
	for (var i in COSTSHEET)
	{
		//Exemption - Material Cost Field
		if(COSTSHEET[i] == COSTSHEET._materialCost) continue;
		nlapiSetFieldValue(COSTSHEET[i], '');
	}
}


/**
 * This function compute total Rate
 * 
 * @returns {Void} 
 */
function computeTotalRateBasedonHours(hrFld, rateFld, totalFld)
{
	var intHr  = parseInt(nlapiGetFieldValue(hrFld));
	var flRate = parseFloat(nlapiGetFieldValue(rateFld)); 

	if(intHr && flRate)
	{
		var flTotal = intHr * flRate;
		nlapiSetFieldValue(totalFld, flTotal);
	}
}

/**
 * This function compute total cost
 * 
 * @returns {float} 
 */
function addTotalCost(arrCostFlds)
{
	var totalCost = 0;
	for(var i in arrCostFlds) 
	{ 
		totalCost += parseFloatHelper(nlapiGetFieldValue(arrCostFlds[i])); 
	}

	return totalCost;
}

/**
 * This function generate the buttons
 * 
 * @returns {Void} 
 */
function setButton(fldName, fldLabel, subtab, callback)
{
	form.addField(fldName, 'inlinehtml', fldLabel, null, subtab);
	nlapiSetFieldValue(fldName, '<button style="width: 150px; margin:5px 0px 5px 0px" class="rndbuttoninpt pgBntG bntBgB" type="button" onclick="'+callback+'">'+fldLabel+'</button>');
}


/**
 * This is a helper function to parse float
 * 
 * @returns {float} 
 */
function parseFloatHelper(number)
{
	if(number)
	{
		return parseFloat(number);
	}
	return 0;
}